package com.kun.service.service;

import cn.hutool.core.util.IdUtil;
import com.kun.common.constant.UserConstant;
import com.kun.common.service.RedisService;
import com.kun.common.util.JsonUtils;
import com.kun.domain.TUser;
import com.kun.domain.TUserInfo;
import com.kun.domain.TRolePermission;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class TokenService {

    @Value("${token.secret}")
    private String secret;

    @Value("${token.expireTime}")
    private Long expireTime;

    private final RedisService redisService;
    private final ITUserInfoService itUserInfoService;
    private SecretKey secretKey;

    public TokenService(RedisService redisService, ITUserInfoService itUserInfoService) {
        this.redisService = redisService;
        this.itUserInfoService = itUserInfoService;
    }

    @PostConstruct
    private void init() {
        // 密钥必须256位，32个字节
        secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 创建 Token
     */
    public String getToken(TUser user) {
        String uuid = IdUtil.getSnowflake().nextIdStr();
        // 获取token
        String token = Jwts.builder()
                .claims().add(UserConstant.LOGIN_USER_KEY, uuid).and()
                .signWith(secretKey).compact();
        TUserInfo tUserInfo = itUserInfoService.selectByUserId(user.getId());
        tUserInfo.setUuid(uuid);
        // 查询权限信息
        List<TRolePermission> tRolePermission = itUserInfoService.queryPermissionByUserId(user.getId());
        tUserInfo.setPermissions(tRolePermission);
        user.setUserInfo(tUserInfo);
        // 存入 redis
        redisService.setKey(UserConstant.LOGIN_TOKEN_KEY + uuid, JsonUtils.toJson(user), expireTime, TimeUnit.MINUTES);
        return token;
    }

    /**
     * 解析 Token
     */
    public TUser parseToken(String token) {
        Claims body = Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload();
        String uuid = (String) body.get(UserConstant.LOGIN_USER_KEY);
        // 存入 redis
        String user = redisService.getKey(UserConstant.LOGIN_TOKEN_KEY + uuid);
        Assert.isTrue(user != null, "token过期");
        return JsonUtils.toBean(user, TUser.class);
    }

    /**
     * 刷新 Token
     */
    public void refreshToken(TUser tUser) {
        // 查询key的过期时间
        String uuid = tUser.getUserInfo().getUuid();
        Assert.isTrue(uuid != null, "Token 已过期");
        Long expireTime1 = redisService.getExpire(UserConstant.LOGIN_TOKEN_KEY + uuid, TimeUnit.MINUTES);
        Assert.isTrue(expireTime != null, "Token 已过期");
        if (expireTime1 < 10)
            redisService.expireKey(UserConstant.LOGIN_TOKEN_KEY + uuid, expireTime, TimeUnit.MINUTES);
    }
}

